<template>
    <div>
        <SelectArea
            homeType="focus"
            @on-edit-info="handleCreate"
            @on-change="handleAreaChange"
        />

        <Card class="no-border-card" style="margin-top:24px;">
            <p slot="title">房间信息</p>
            <Row :gutter="20" class="home-create__tools">
                <i-col :span="6" v-if="canUsingBuildingRoom">
                    <div class="home-create__tools__key">楼栋数量</div>
                    <InputNumber class="home-create__tools__item" :min="1" :max="99" :precision="0" v-model="roomModel.buildingCount"></InputNumber>
                </i-col>
                <i-col :span="6">
                    <div class="home-create__tools__key">{{canUsingBuildingRoom ? '每栋' : '' }}楼层数</div>
                    <InputNumber class="home-create__tools__item" :min="1" :max="99" :precision="0" v-model="roomModel.eachBuildingFloors"></InputNumber>
                </i-col>
                <i-col :span="6">
                    <div class="home-create__tools__key">每层房间数</div>
                    <InputNumber class="home-create__tools__item" :min="1" :max="99" :precision="0" v-model="roomModel.eachFloorRooms"></InputNumber>
                </i-col>
                <i-col :span="6">
                    <div class="home-create__tools__key">{{canUsingBuildingRoom ? '每栋' : '' }}起始楼层</div>
                    <InputNumber class="home-create__tools__item" :min="1" :max="99" :precision="0" v-model="roomModel.startFloor"></InputNumber>
                </i-col>
            </Row>
            <Row :gutter="20" class="home-create__tools" style="margin-bottom: 30px">
                <i-col :span="6">
                    <div class="home-create__tools__key">
                        <Checkbox v-model="canRemoveFloors" @on-change="val => handleCheckBoxChange('shouldRemoveFloors', val)">去除指定楼层</Checkbox>
                    </div>
                    <i-input type="text" v-model="roomModel.shouldRemoveFloors" :disabled="!canRemoveFloors" placeholder="填入楼层数字，多个楼层用空格隔开"></i-input>
                </i-col>
                <i-col :span="6">
                    <div class="home-create__tools__key">
                        <Checkbox v-model="canIgnoreRooms" @on-change="val => handleCheckBoxChange('shouldIgnoreRooms', val)">去除含义以下数字的房间</Checkbox>
                    </div>
                    <i-input type="text" v-model="roomModel.shouldIgnoreRooms" :disabled="!canIgnoreRooms" placeholder="填入数字，多个数字用空格隔开"></i-input>
                </i-col>
                <i-col :span="12">
                    <div class="home-create__tools__key">&nbsp;</div>
                    <i-button type="primary" @click="handleGenerate">生成房间</i-button>
                    <i-button type="primary" @click="handleReset">清空房间</i-button>
                </i-col>
            </Row>
            <Alert class="margin-bottom-20" v-if="canUsingBuildingRoom">
                注：多栋模式下，公区也只能绑定1个门锁，1个电表，1个冷水和1个热水表
            </Alert>
            <div>
                <div :class="['home-create__building__container', { 'is-overflow': isOverflow }]">
                    <div class="home-create__left__arrow" v-show="isOverflow" @click="handleScrollLeft">
                        <Icon type="chevron-left"></Icon>
                    </div>
                    <div class="home-create__right__arrow" v-show="isOverflow" @click="handleScrollRight">
                        <Icon type="chevron-right"></Icon>
                    </div>
                    <div
                        :class="['home-create__building__list', { 'is-overflow': isOverflow }]"
                        :style="'transform:translateX(' + buildListXPosition + 'px)'"
                        v-if="canUsingBuildingRoom"
                        ref="buildingList">
                        <div
                            :class="['home-create__building__item', { 'is-selected': index === currentBuildingIndex }]"
                            v-for="(building, index) in buildings"
                            :key="building.building_name"
                            @click="handleBuildingChange(index)">
                            <span class="home-create__building__name">{{building.building_name}}</span>
                            <div class="home-create__building__btns">
                                <a
                                    class="home-create__building__btn"
                                    href="javascript:;"
                                    @click.prevent="handleEditBuildingName(building.building_name, index)">
                                    编辑
                                </a>
                                <a
                                    class="home-create__building__btn"
                                    href="javascript:;"
                                    @click.prevent="handleDeleteBuilding(index)">
                                    删除
                                </a>
                            </div>
                        </div>
                    </div>
                </div>
                <template v-if="buildings[currentBuildingIndex]">
                    <div
                        class="home-create__focus__room__row"
                        v-for="floor in buildings[currentBuildingIndex].floors"
                        :key="floor.floor_num">
                        <div class="home-create__focus__room__title">
                            {{floor.floor_num}}层
                        </div>

                        <div class="home-create__focus__room__list">
                            <div
                                class="home-create__focus__room__item__wrap"
                                v-for="(room, roomIndex) in floor.rooms"
                                :key="roomIndex">
                                <i-input v-model="room.name">
                                    <Icon
                                        slot="append"
                                        class="home-create__focus__room__delete"
                                        type="ios-close-empty"
                                        @click="handleDeleteRoom(floor, roomIndex, floorIndex)">
                                    </Icon>
                                </i-input>
                            </div>
                        </div>
                    </div>
                </template>
            </div>
        </Card>
    </div>
</template>

<script>
    import debounce from 'lodash/debounce'
import flatten from 'lodash/flatten'
import countBy from 'lodash/countBy'
import SelectArea from '../selectArea'
import { http, api } from '@/libs/http'

export default {
      name: 'create-focus-home',
      components: {
        SelectArea
      },
      data () {
        return {
          submiting: false,
          buildListXPosition: 0,
          canRemoveFloors: false,
          canIgnoreRooms: false,
          roomModel: {
            shouldRemoveFloors: '',
            shouldIgnoreRooms: '',
            buildingCount: 1,
            eachBuildingFloors: 1,
            eachFloorRooms: 1,
            startFloor: 1
          },
          areaData: {}, // 地址等信息
          maxRoomCount: 1000,
          /**
                 * 数据结构: [{building_name, floors: [ floor_num, rooms: [{name}] ] }]
                 */
          buildings: [],
          currentBuildingIndex: 0,
          isOverflow: false
        }
      },
      computed: {
        currentBuilding () {
          if (!this.buildings[this.currentBuildingIndex]) return {}
          return this.buildings[this.currentBuildingIndex]
        },
        canUsingBuildingRoom () {
          return this.$store.state.user.hasFaceAccessPermission
        }
      },
      mounted () {
        window.addEventListener('resize', this.onResize)
      },
      methods: {
        onResize: debounce(function () {
          this.checkBuildListWith()
        }, 200),
        buildListClientWith () { // 显示长度
          return this.$refs.buildingList.clientWidth
        },
        buildListScrollWith () { // 总长度加hover长度
          return this.$refs.buildingList.scrollWidth + 110
        },
        checkBuildListWith () {
          if (!this.canUsingBuildingRoom || !this.$refs.buildingList) return
          this.isOverflow = this.$refs.buildingList.scrollWidth > this.$refs.buildingList.clientWidth
        },
        handleScrollLeft () {
          if (this.buildListXPosition >= 0) this.buildListXPosition = 0
          const scrollWith = Math.floor(this.buildListClientWith() * 0.7)
          if (this.buildListXPosition + scrollWith > 0) {
            this.buildListXPosition = 0
          } else {
            this.buildListXPosition += scrollWith
          }
        },
        handleScrollRight () {
          const scrollWidth = Math.floor(this.buildListClientWith() * 0.7)
          if (Math.abs(this.buildListXPosition - scrollWidth) > this.buildListScrollWith()) {
            this.buildListXPosition = -(this.buildListScrollWith() - 350)
            return
          }
          this.buildListXPosition -= Math.floor(this.buildListClientWith() * 0.7)
        },
        handleCheckBoxChange (filed, val) {
          if (!val) this.roomModel[filed] = ''
        },
        handleBuildingChange (index) {
          this.currentBuildingIndex = index
        },
        async handleCreate () {
          if (this.submiting) return
          if (!this.validRoom()) return
          this.submiting = true
          const submiting = this.$Message.loading({
            content: '提交中...',
            duration: 0
          })
          try {
            const homeData = this.getCreateHomeData()
            const roomData = this.getCreateRoomData()

            const home = await http.req(api.home_create, null, homeData)
            if (!home) throw new Error('创建房源失败')
            await http.req(api.room_create, [ home.home_id ], roomData)
            this.$Message.success('创建成功')
            this.$emit('success')
          } catch (err) {
            console.log(err)
          } finally {
            this.submiting = false
            submiting()
          }
        },
        /**
             * 创建前检查是否有房间和同栋房间名是否重复
             */
        validRoom () {
          if (this.buildings.length === 0 || this.buildings[0].floors.length === 0) {
            this.$Message.info('请创建房间')
            return false
          }
          const duplicateResult = []
          const illegalResult = []
          this.buildings.forEach(building => {
            /** 统计名字重复的房间数量 */
            const roomsCount = countBy(flatten(building.floors.map(f => f.rooms)), 'name')
            const [ duplicateRoomNames, illegalNames ] = Object.keys(roomsCount).reduce(([ wrongNames, illegalNames ], roomName) => {
              if (roomsCount[roomName] > 1) wrongNames.push(roomName)
              if (!/^[\w\u4e00-\u9fa5-]{1,15}$/g.test(roomName)) illegalNames.push(roomName)
              return [ wrongNames, illegalNames ]
            }, [ [], [] ])
            const prefix = this.canUsingBuildingRoom ? `楼栋${building.building_name}: ` : ''
            if (duplicateRoomNames.length) {
              duplicateResult.push(`${prefix}${duplicateRoomNames.join(' ')}`)
            }
            if (illegalNames.length) {
              illegalResult.push(`${prefix}${illegalNames.join(' ')}`)
            }
          })
          if (duplicateResult.length || illegalResult.length) {
            this.$Modal.confirm({
              render: h => (
                <div>
                  <div class='margin-bottom-20'><strong>创建失败</strong></div>
                  { duplicateResult.length > 0 && <div class='margin-bottom-10'>以下房间名重复</div> }
                  {
                    duplicateResult.map((detail, index) => <div class='margin-bottom-10' key={index}>{detail}</div>)
                  }
                  { illegalResult.length > 0 && <div class='margin-bottom-10'>以下房间名请使用15位以内的中英文/数字/-连接的组合</div> }
                  {
                    illegalResult.map((detail, index) => <div key={index}>{detail}</div>)
                  }
                </div>
              )
            })
            return false
          }
          return true
        },
        /** 返回创建房源需要的参数 */
        getCreateHomeData () {
          const { home_name, street, block, area, city, province, doorNumber, branch_id } = this.areaData
          return {
            home_name: home_name,
            home_type: 2,
            street: street,
            block: block,
            district: area,
            city: city,
            province: province,
            country: '中国',
            number: doorNumber,
            description: home_name,
            branch_id: branch_id || 0
          }
        },
        /**
             * 返回创建房间需要的参数,
             * canUsingBuildingRoom 没有门禁权限的商户只能创建一栋, 并且展示跟原有的集中式相同,
             * 有权限的则显示栋数
             */
        getCreateRoomData () {
          const { canUsingBuildingRoom, buildings } = this
          // 没有楼栋权限只能创建一栋
          return canUsingBuildingRoom
            ? { building_floor_rooms: buildings }
            : { floor_rooms: buildings[0].floors }
        },
        handleReset () {
          this.currentBuildingIndex = 0
          this.buildings = []
        },
        handleAreaChange (data) {
          this.areaData = data
        },
        /**
             * 循环逻辑,
             * loop 总循环次数, 遇到过滤则不减少
             */
        handleGenerate () {
          this.currentBuildingIndex = 0
          this.buildings = []
          this.buildListXPosition = 0
          const {
            shouldRemoveFloors,
            shouldIgnoreRooms,
            buildingCount,
            eachBuildingFloors,
            eachFloorRooms,
            startFloor } = this.roomModel
          const removeFloors = this.uniqueStringToNumber(shouldRemoveFloors)
          const ignoreRooms = this.uniqueStringToNumber(shouldIgnoreRooms)

          if (!startFloor || !buildingCount || !eachFloorRooms || !eachBuildingFloors) {
            this.$Message.info('请填写完整的房间生成选项')
            return
          }
          const start = startFloor || 1
          const buildingSum = buildingCount || 1 // 总栋数
          const roomsPerFloor = eachFloorRooms || 1 // 每层楼房间数
          const floorPerBuilding = eachBuildingFloors || 1 // 每栋楼层数
          const buildings = []
          let roomsCount = 0
          for (let buildingIndex = 1; buildingIndex <= buildingSum; buildingIndex++) {
            const floors = []
            const buildingName = `${buildingIndex}栋`
            let loop = floorPerBuilding
            let floor = start
            while (loop > 0) {
              if (!removeFloors.includes(floor)) {
                floors.push({
                  floor_num: floor,
                  rooms: this.generateRoom(floor, roomsPerFloor, ignoreRooms)
                })
                roomsCount += roomsPerFloor
                loop -= 1
                floor += 1
              } else {
                floor += 1 // 不是包含的楼层则增加当前楼层位置
              }
            }
            buildings.push({ building_name: buildingName, floors })
          }

          if (this.isUnderLimit(roomsCount)) {
            this.buildings = buildings
            this.$nextTick(() => {
              this.checkBuildListWith()
            })
          }
        },
        isUnderLimit (sum) {
          const result = sum <= this.maxRoomCount
          if (!result) this.$Message.error(`请勿超过${this.maxRoomCount}个房间`)
          return result
        },
        /**
             * 生成房间列表
             * @param {number} 房间的的楼层
             * @param {number} 每层楼的房间数
             * @param {number[]} 不需要的房间数字
             * @return {{ name }[]} 房间名对象数组
             */
        generateRoom (floor, roomsPerFloor, ignoreRooms) {
          const floorPlaceholder = floor < 10 ? `0${floor}` : `${floor}`
          let roomCount = 1
          let loop = roomsPerFloor
          const result = []
          while (loop > 0) {
            // 字符串包含不需要的数字的房间跳过
            const isIllegalRoomName = ignoreRooms.some(roomNumber => String(roomCount).includes(String(roomNumber)))
            if (!isIllegalRoomName) {
              const roomPlaceholder = roomCount < 10 ? `0${roomCount}` : `${roomCount}`
              result.push({ name: floorPlaceholder + roomPlaceholder })
              loop -= 1
            }
            roomCount += 1
          }
          return result
        },
        /**
             * 将以空格分割的字符串转换成数字数组
             * @param {string} string 空格分割的字符串
             * @return {number[]} 不需要的数字列表
             */
        uniqueStringToNumber (string) {
          if (typeof string !== 'string' || !string) return []
          return string.split(' ').reduce((result, item) => {
            if (/\d/g.test(item) && !result.includes(item)) return result.concat([Number(item)])
            return result
          }, [])
        },
        handleDeleteBuilding (buildingIndex) {
          this.buildings.splice(buildingIndex, 1)
          this.$nextTick(() => {
            this.currentBuildingIndex = 0
          })
        },
        handleDeleteRoom (floor, roomIndex, floorIndex) {
          if (this.currentBuilding.floors.length === 1 && this.currentBuilding.floors[0].rooms.length === 1) {
            this.$Message.info('只剩最后一个房间, 删除失败')
            return
          }
          floor.rooms.splice(roomIndex, 1)
          if (floor.rooms.length === 0) {
            this.buildings[this.currentBuildingIndex].floors.splice(floorIndex, 1)
          }
        },
        handleEditBuildingName (name, buildingIndex) {
          let newName = name
          this.$Modal.confirm({
            title: '新名称',
            render: h => {
              return (
                <div>
                  <i-input
                    value={newName}
                    onInput={val => { newName = (val + '').trim() }}
                  >
                  </i-input>
                </div>
              )
            },
            onOk: () => {
              if (newName === name || !this.checkBuildingName(newName)) {
                return
              }
              this.$set(this.buildings[buildingIndex], 'building_name', newName)
            }
          })
        },
        checkBuildingName (name) {
          const buildingNames = this.buildings.map(b => b.building_name)
          if (!name) {
            this.$Message.info('请填写楼栋名')
            return false
          } else if (buildingNames.includes(name)) {
            this.$Message.info('楼栋已存在')
            return false
          } else if (!/^[\w\u4e00-\u9fa5-]{1,15}$/g.test(name)) {
            this.$Message.info({
              content: '请使用15位以内的中英文/数字/-连接的组合',
              duration: 4
            })
            return false
          }
          return true
        },
        /** 用于更新房间信息, name, floor */
        async updateRoomInfo (rooms) {
          if (rooms.some(r => !r.id || (!r.name || !r.floor))) {
            this.$Message.error('接口使用错误')
            return
          }
          await http.req(api.room_update_multiple, [ this.home.id ], rooms)
        }
      },
      beforeDestroy () {
        window.removeEventListener('resize', this.onResize)
      }
    }
</script>

<style lang="less">
    @import url('../home');
</style>